package uqbar.aspectj.observable.simple;

import uqbar.aspectj.utils.Utils;

/**
 * A simple observable aspect that logs an event in the sysout everytime a field
 * is written with a different value than the current one.
 * 
 * @author uqbar
 */
public aspect SysoutSimpleObservableAspect {
	public int counter = 0;

	pointcut fieldWrite(Object target, Object newValue) : 
		set(* examples.simple..*) && args(newValue) && target(target);

	pointcut setter(Object target, Object newValue) : 
		call(* examples.simple..set*(*)) && args(newValue) && target(target);

	void around(Object target, Object newValue) : setter(target, newValue) {
		proceed(target, newValue);
		System.out.println("Se llamó al setter");
	}

	void around(Object target, Object newValue) : fieldWrite(target, newValue) {
		String fieldName = thisJoinPoint.getSignature().getName();
		Object oldValue = Utils.getField(target, fieldName);

		proceed(target, newValue);

		// comparar por null y por equals ?
		if (oldValue != newValue) {
			this.notifyFieldChanged(target, fieldName, oldValue, newValue,
					thisJoinPoint.getThis());
		}
	}

	protected void notifyFieldChanged(Object target, String fieldName,
			Object oldValue, Object newValue, Object self) {

		this.counter++;
		System.out.println("Updated field :" + target + "." + fieldName
				+ " from " + self + " (" + oldValue + " -> " + newValue + ")");
	}

}